#include <stdio.h>
#include <stdlib.h>
#include "democlass.h"

static void cpeople_show_attribute(CPeople *people);
static void cpeople_ability(CPeople* people);
static void init_cpeople(CPeople *object);
static void init_cpeople_class(CPeopleClass *vclass);
void cpeople_destroy(CObject *obj);

static CObjectClass *cpeople_parent_class = NULL;

/*******************************************************************/

static void cteacher_show_attribute(CPeople *people);
static void cteacher_ability(CPeople *people);
static void init_cteacher(CTeacher *object);
static void init_cteacher_class(CTeacherClass *vclass);
static void cteacher_destroy(CObject *obj);

static CPeopleClass *cteacher_parent_class = NULL;

static void cpeople_show_attribute(CPeople *people)
{
	if(people == NULL)
		return;
	
	printf("People : My name is %s,age is %d,height is %d\n",people->name,people->age,people->height);
}

static void cpeople_ability(CPeople* people)
{
	if(people == NULL)
		return;
	
	printf("People: I can walk.\n");
}

static void init_cpeople(CPeople *people)
{
	if(people == NULL)
		return;
	
	people->age = 0;
	people->height = 0;
	people->name = (char *)malloc(50);

	sprintf(people->name,"A People");

	printf("construct cpeople\n");
}

static void init_cpeople_class(CPeopleClass *vclass)
{
	CObjectClass *obj_class = COBJECT_CLASS(vclass);

	if(obj_class == NULL)
		return;
	
	obj_class->destroy = cpeople_destroy;
	vclass->show_attribute = cpeople_show_attribute;
	vclass->ability = cpeople_ability;

	cpeople_parent_class = CPEOPLE_PARENT_CLASS(vclass);
}

void cpeople_destroy(CObject *obj)
{
	CPeople *people = CPEOPLE(obj);
	
	if(people == NULL)
		return;

	if(people->name != NULL)
	{
		free(people->name);
		printf("destroy cpeople\n");
	}

	COBJECT_CLASS(cpeople_parent_class)->destroy(obj);
}

u32 get_cpeople_type(void)
{
	static u32 type = 0;
	ClassType *pclass;
	
	if( type==0 )
	{
		static ClassInfo classinfo = 
		{
			"CPEOPLE",
				sizeof(CPeople),
				sizeof(CPeopleClass),
				(init_object_callback)init_cpeople,
				(init_class_callback)init_cpeople_class,
		};
		
		type = register_class_type(&classinfo, COBJECT_TYPE);
	}
	pclass = (ClassType*)type;
	return type;
}

CPeople* cpeople_new(void)
{
	return (CPeople*)g_object_new(CPEOPLE_TYPE);
}

/****************************************************************/

static void cteacher_show_attribute(CPeople *people)
{
	CTeacher *teacher = CTEACHER(people);
	
	if(teacher == NULL)
		return;

	printf("People : My name is %s,age is %d,height is %d teach %s\n",people->name,people->age,people->height,teacher->subject);
}

static void cteacher_ability(CPeople *people)
{
	CTeacher *teacher = CTEACHER(people);
	
	if(teacher == NULL)
		return;

	
	printf("teacher: I can teach people.\n");
}

static void init_cteacher(CTeacher *teacher)
{
	if(teacher == NULL)
		return;

	teacher->subject = (char *)malloc(50);

	sprintf(teacher->subject,"a subject");
	
	printf("construct cteacher\n");
}

static void init_cteacher_class(CTeacherClass *vclass)
{
	CObjectClass *obj_class = COBJECT_CLASS(vclass);
	CPeopleClass *people_class = (CPeopleClass *)vclass;

	
	if(people_class == NULL)
		return;
	
	obj_class->destroy = cteacher_destroy;
	people_class->show_attribute = cteacher_show_attribute;
	people_class->ability = cteacher_ability;

	cteacher_parent_class = CTEACHER_PARENT_CLASS(vclass);
}

static void cteacher_destroy(CObject *obj)
{
	CTeacher *teacher = CTEACHER(obj);

	if(teacher == NULL)
		return;

	if(teacher->subject != NULL)
	{
		free(teacher->subject);
		printf("destroy cteacher\n");
	}

	COBJECT_CLASS(cteacher_parent_class)->destroy(obj);
}

u32 get_cteacher_type(void)
{
	static u32 type = 0;
	
	if( type==0 )
	{
		static ClassInfo classinfo = 
		{
			"CTEACHER",
				sizeof(CTeacher),
				sizeof(CTeacherClass),
				(init_object_callback)init_cteacher,
				(init_class_callback)init_cteacher_class,
		};
		
		type = register_class_type(&classinfo, CPEOPLE_TYPE);
	}
	
	return type;
}

CTeacher* cteacher_new(void)
{
	return (CTeacher*)g_object_new(CTEACHER_TYPE);
}
